package com.biqee.service.hao123.impl;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.biqee.model.db.Hao123StyleItem;
import com.biqee.service.crawler.PageFetcher;
import com.biqee.service.hao123.Hao123StyleItemService;
import com.biqee.service.hao123.Hao123XmlParseService;

public class Hao123XmlParseServiceImpl implements Hao123XmlParseService {
	private static final Logger logger = Logger.getLogger(Hao123XmlParseServiceImpl.class);
	
	@Override
	public List<Hao123StyleItem> parse(String xmlContent) {
		InputStream inputStream = new ByteArrayInputStream(xmlContent.getBytes());
		return parse(inputStream);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public List<Hao123StyleItem> parse(InputStream inputStream) {
		List<Hao123StyleItem> result = new ArrayList<Hao123StyleItem>();
		SAXBuilder builder = new SAXBuilder(false);
		try {
			Document document = builder.build(inputStream);
			Element rootElement = document.getRootElement();
			List urlElements = rootElement.getChildren("url");   
			for(int i=0; i < urlElements.size(); i++) {
				Element urlElement = (Element)urlElements.get(i);
				Hao123StyleItem element = parseHao123StyleItem(urlElement);
				result.add(element);
			}
		} catch (JDOMException ex) {
			logger.error("parse failed", ex);
		} catch (IOException ex) {
			logger.error("parse failed", ex);
		}
		
		return result;
	}

	@Override
	public void parseAll() {
		for(String key : targets.keySet()){  
			String target = targets.get(key);  
			logger.info("access key: " + key + ", target: " + target);
			try {
				List<Hao123StyleItem> resultList = parseTarget(target);
				dealWithResultList(resultList);
			} catch (Exception ex) {
				// 这里做异常捕获，防止某一网站的失败影响其他网站
				logger.info("parse failed. key: " + key + 
						", target: " + target + 
						", exception: ", ex);
			}
		}
	}
	
	private void dealWithResultList(List<Hao123StyleItem> resultList) {
		for(Hao123StyleItem hao123StyleItem : resultList) {
			hao123StyleItemService.save(hao123StyleItem);
		}
	}
	
	private List<Hao123StyleItem> parseTarget(String target) {
		String xmlContent = pageFetcher.getAsStringWithSpiderHeader(target, null);
		return parse(xmlContent);
	}
	
	private Hao123StyleItem parseHao123StyleItem(Element urlElement) {
		String loc = urlElement.getChildTextTrim("loc");
		Element dataElement = urlElement.getChild("data");
		Element displayElement = dataElement.getChild("display");
		String webSite = displayElement.getChildTextTrim("website");
		String siteUrl = displayElement.getChildTextTrim("siteurl");
		String city = displayElement.getChildTextTrim("city");
		String category = displayElement.getChildTextTrim("category");
		String dpShopId = displayElement.getChildTextTrim("dpshopid");
		String range = displayElement.getChildTextTrim("range");
		String address = displayElement.getChildTextTrim("address");
		String major = displayElement.getChildTextTrim("major");
		String image = displayElement.getChildTextTrim("image");
		String startTime = displayElement.getChildTextTrim("startTime");
		String endTime = displayElement.getChildTextTrim("endTime");
		String value = displayElement.getChildTextTrim("value");
		String price = displayElement.getChildTextTrim("price");
		String rebate = displayElement.getChildTextTrim("rebate");
		String bought = displayElement.getChildTextTrim("bought");
		String title = displayElement.getChildTextTrim("title");
			
		Hao123StyleItem item = new Hao123StyleItem();
		item.setAddress(address);
		item.setBought(bought);
		item.setCategory(category);
		item.setCity(city);
		item.setDpShopId(dpShopId);
		item.setEndTime(endTime);
		item.setImage(image);
		item.setLoc(loc);
		item.setMajor(major);
		item.setPrice(price);
		item.setRange(range);
		item.setRebate(rebate);
		item.setSiteUrl(siteUrl);
		item.setStartTime(startTime);
		item.setTitle(title);
		item.setValue(value);
		item.setWebSite(webSite);
		
		return item;
	}
	
	private Map<String, String> targets;
	
	public void setTargets(Map<String, String> targets) {
		this.targets = targets;
	}

	private PageFetcher pageFetcher;
	
	public void setPageFetcher(PageFetcher pageFetcher) {
		this.pageFetcher = pageFetcher;
	}

	private Hao123StyleItemService hao123StyleItemService;
	
	public void setHao123StyleItemService(
			Hao123StyleItemService hao123StyleItemService) {
		this.hao123StyleItemService = hao123StyleItemService;
	}

	public static void main(String[] args) throws FileNotFoundException {
		String filePath = "D:\\work\\biqee\\test-pages\\hao123\\test.xml";
		File file = new File(filePath);
		InputStream inputStream = new FileInputStream(file);
		Hao123XmlParseService parseService = new Hao123XmlParseServiceImpl();
		List<Hao123StyleItem> items = parseService.parse(inputStream);
		for(Hao123StyleItem item : items) {
			String desc = ToStringBuilder.reflectionToString(item, ToStringStyle.MULTI_LINE_STYLE);
			System.out.println(desc);
		}
	}
}
